﻿using System;

namespace Csharp虚方法
{

class Program
    {
        static void Main(string[] args)
        {
            #region 面向对象
            //虚方法的目的-----------》同一个目的达到不同效果

            //多态：为了解决同一种指令，可以有不同的行为和结果
            //虚方法---抽象类---抽象函数---接口

            //多态经常和继承搭配使用

            //虚方法：
            //      被virtual关键字修饰的方法，叫做虚方法
            //      虚方法通常写你要继承的父类中
            //      然后子类可以通过override关键字重写虚方法-----注意不是重载，是重写

            //      让我不同的子类对同一指令有不同的行为

            #region 非虚方法的调用
            //for (int i = 0; i < 10; i++) 
            //{
            //    int rate = r.Next(1,101);
            //    if (rate >= 80)//20%的纪律
            //    {
            //        monsters[i] = new Boss("第" + i + "号Boss");
            //    }
            //    else 
            //    {
            //        monsters[i] = new Goblin("第" + i + "号Goblin");
            //    }      
            //}

            ////放招
            //for (int i = 0; i < monsters.Length; i++)
            //{
            //    if (monsters[i] is Boss) //判断能不能转换
            //    {

            //        Boss temp = monsters[i] as Boss;
            //        temp.Skill();
            //    }
            //    else 
            //    {
            //        monsters[i].Attack();
            //    }
            //}
            #endregion


            #region 虚方法调用
            //Monster[] list = new Monster[10];
            //for (int i=0;i<list.Length;i++) 
            //{
            //    if (i == 9)
            //    {
            //        list[i] = new Boss("奥妮克希亚");
            //    }
            //    else 
            //    {
            //        list[i] = new Goblin("第"+i+"哥布林");
            //    }
            //}

            //for (int i = 0; i < list.Length; i++)
            //{
            //    list[i].Attack();
            //}


            //1.虚方法在调用，会根据你运行时，实际对象和最后重写的方法，去决定运行哪一个
            //2.如果你是非虚方法，要用is先判断，然后as转成对应的对象，才能去执行对于的方法

            //3.子类只能重写同参数列表同返回类型同名的虚方法
            //4.不要在子类中去申明一个和虚方法同名的新方法，会被new给隐藏掉



            #endregion

            #region 鸭子

            //realduck td = new realduck();
            //td.name = "真鸭子";


            //woodduck wd = new woodduck();
            //wd.name = "木头鸭子";


            //xiangpiduck xd = new xiangpiduck();
            //xd.name = "橡皮鸭子";


            //td.duckSHow();

            //wd.duckSHow();

            //xd.duckSHow();




            #endregion

            #region 经理打卡

            //person employee = new Employee();
            //employee.name = "员工";


            //person manager = new Manager();
            //manager.name = "经理";

            //person prommger = new Programmer();
            //prommger.name = "程序员";
            //Console.WriteLine(prommger.ToString());

            //employee.ClockIn();
            //manager.ClockIn();
            //prommger.ClockIn();

            #endregion

            #region 抽象方法----abstract
            //抽象方法是没有实现代码的虚方法
            //使用的是abstract修饰符进行声明，只能放在同样声明了abstract的类中使用
            //继承了抽象的子类必须实现抽象类的所有抽象方法
            //用abstract修饰过的类是抽象类
            //抽象类无法被实例化
            //子类如果继承自抽象类，那么子类必须实现abstract类中所有的abstract成员

            //<-------------------------------------------------------->
            //1.抽象方法必须放在抽象类
            //2.抽象方法不可以实现代码-----用空语句代替块
            //3.抽象方法可以用override关键字重写
            //4.继承了抽象类的子类 必须实现abstract类中所有的abstract成员
            //5.抽象类不能实例化，类似先提出一个概念



            //如果你的父类需要实例化，且需要实现方法，用虚方法
            //如果你的父类不需要实例化，也不需要实现方法，用抽象类和抽象方法


            //student s = new student();
            //s.name = "小明";
            //s.SayHello();




            #endregion


            #region 动物抽象类

            //dog d = new dog();
            //d.name = "小狗";
            //d.animShow();


            //cat c = new cat();
            //c.name = "小猫";
            //c.animShow();


            #endregion




            #endregion
        }
    }
}
